import { request } from './index'
import type { ApiResponse, PaginatedResponse } from '@/types'

/**
 * API服务基类
 * 提供通用的CRUD操作方法
 */
export abstract class BaseApiService<T = any> {
  protected baseUrl: string

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
  }

  /**
   * 获取列表
   */
  async getList(params?: Record<string, any>): Promise<PaginatedResponse<T>> {
    return request.get(`${this.baseUrl}`, { params })
  }

  /**
   * 根据ID获取详情
   */
  async getById(id: number | string): Promise<ApiResponse<T>> {
    return request.get(`${this.baseUrl}/${id}`)
  }

  /**
   * 创建新记录
   */
  async create(data: Partial<T>): Promise<ApiResponse<T>> {
    return request.post(`${this.baseUrl}`, data)
  }

  /**
   * 更新记录
   */
  async update(id: number | string, data: Partial<T>): Promise<ApiResponse<T>> {
    return request.put(`${this.baseUrl}/${id}`, data)
  }

  /**
   * 删除记录
   */
  async delete(id: number | string): Promise<ApiResponse> {
    return request.delete(`${this.baseUrl}/${id}`)
  }

  /**
   * 批量删除
   */
  async batchDelete(ids: (number | string)[]): Promise<ApiResponse> {
    return request.post(`${this.baseUrl}/batch-delete`, { ids })
  }

  /**
   * 搜索
   */
  async search(params: Record<string, any>): Promise<PaginatedResponse<T>> {
    return request.get(`${this.baseUrl}/search`, { params })
  }

  /**
   * 获取统计信息
   */
  async getStatistics(): Promise<ApiResponse> {
    return request.get(`${this.baseUrl}/statistics`)
  }
}

/**
 * 文件上传服务基类
 */
export abstract class BaseUploadService {
  protected baseUrl: string

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
  }

  /**
   * 单文件上传
   */
  async uploadSingle(
    file: File, 
    onProgress?: (progress: number) => void
  ): Promise<ApiResponse> {
    const formData = new FormData()
    formData.append('file', file)
    
    return request.post(`${this.baseUrl}/single`, formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      onUploadProgress: (progressEvent: any) => {
        if (onProgress && progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
          onProgress(progress)
        }
      }
    })
  }

  /**
   * 批量文件上传
   */
  async uploadBatch(
    files: File[], 
    onProgress?: (progress: number) => void
  ): Promise<ApiResponse> {
    const formData = new FormData()
    files.forEach(file => {
      formData.append('files', file)
    })
    
    return request.post(`${this.baseUrl}/batch`, formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
      onUploadProgress: (progressEvent: any) => {
        if (onProgress && progressEvent.total) {
          const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
          onProgress(progress)
        }
      }
    })
  }
}

/**
 * API响应处理工具
 */
export class ApiResponseHandler {
  /**
   * 处理API响应
   */
  static handle<T>(response: ApiResponse<T>): T {
    if (response.success) {
      return response.data as T
    }
    throw new Error(response.message || 'API请求失败')
  }

  /**
   * 处理分页响应
   */
  static handlePaginated<T>(response: PaginatedResponse<T>): {
    data: T[]
    pagination: PaginatedResponse<T>['pagination']
  } {
    if (response.success) {
      return {
        data: response.data || [],
        pagination: response.pagination
      }
    }
    throw new Error(response.message || 'API请求失败')
  }

  /**
   * 安全处理API响应（不抛出异常）
   */
  static safeHandle<T>(response: ApiResponse<T>): {
    success: boolean
    data?: T
    error?: string
  } {
    try {
      const data = this.handle(response)
      return { success: true, data }
    } catch (error) {
      return { 
        success: false, 
        error: error instanceof Error ? error.message : '未知错误' 
      }
    }
  }
}

/**
 * API缓存管理
 */
export class ApiCache {
  private static cache = new Map<string, {
    data: any
    timestamp: number
    ttl: number
  }>()

  /**
   * 设置缓存
   */
  static set(key: string, data: any, ttl: number = 5 * 60 * 1000): void {
    this.cache.set(key, {
      data,
      timestamp: Date.now(),
      ttl
    })
  }

  /**
   * 获取缓存
   */
  static get<T>(key: string): T | null {
    const item = this.cache.get(key)
    if (!item) return null

    const now = Date.now()
    if (now - item.timestamp > item.ttl) {
      this.cache.delete(key)
      return null
    }

    return item.data as T
  }

  /**
   * 删除缓存
   */
  static delete(key: string): void {
    this.cache.delete(key)
  }

  /**
   * 清空缓存
   */
  static clear(): void {
    this.cache.clear()
  }

  /**
   * 生成缓存键
   */
  static generateKey(url: string, params?: Record<string, any>): string {
    const paramStr = params ? JSON.stringify(params) : ''
    return `${url}:${paramStr}`
  }
}

/**
 * API重试机制
 */
export class ApiRetry {
  /**
   * 重试执行API请求
   */
  static async execute<T>(
    apiCall: () => Promise<T>,
    maxRetries: number = 3,
    delay: number = 1000
  ): Promise<T> {
    let lastError: Error

    for (let i = 0; i <= maxRetries; i++) {
      try {
        return await apiCall()
      } catch (error) {
        lastError = error instanceof Error ? error : new Error('未知错误')
        
        if (i === maxRetries) {
          throw lastError
        }

        // 指数退避延迟
        const retryDelay = delay * Math.pow(2, i)
        await new Promise(resolve => setTimeout(resolve, retryDelay))
      }
    }

    throw lastError!
  }

  /**
   * 判断是否应该重试
   */
  static shouldRetry(error: any): boolean {
    // 网络错误或5xx服务器错误应该重试
    if (!error.response) return true
    
    const status = error.response.status
    return status >= 500 || status === 408 || status === 429
  }
}

/**
 * API请求队列管理
 */
export class ApiQueue {
  private static queue: Array<{
    id: string
    request: () => Promise<any>
    resolve: (value: any) => void
    reject: (error: any) => void
  }> = []
  
  private static processing = false
  private static concurrency = 5
  private static activeRequests = 0

  /**
   * 添加请求到队列
   */
  static async add<T>(request: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      const id = Date.now().toString() + Math.random().toString(36).substr(2, 9)
      
      this.queue.push({
        id,
        request,
        resolve,
        reject
      })

      this.process()
    })
  }

  /**
   * 处理队列
   */
  private static async process(): Promise<void> {
    if (this.processing || this.activeRequests >= this.concurrency) {
      return
    }

    this.processing = true

    while (this.queue.length > 0 && this.activeRequests < this.concurrency) {
      const item = this.queue.shift()
      if (!item) continue

      this.activeRequests++

      item.request()
        .then(item.resolve)
        .catch(item.reject)
        .finally(() => {
          this.activeRequests--
          this.process()
        })
    }

    this.processing = false
  }

  /**
   * 清空队列
   */
  static clear(): void {
    this.queue.forEach(item => {
      item.reject(new Error('请求队列已清空'))
    })
    this.queue = []
  }

  /**
   * 获取队列状态
   */
  static getStatus(): {
    queueLength: number
    activeRequests: number
    concurrency: number
  } {
    return {
      queueLength: this.queue.length,
      activeRequests: this.activeRequests,
      concurrency: this.concurrency
    }
  }
}